# coding=utf-8
class Parent(object):  # 定义父类
    parentAttr = 100
    _protected_val = '我只能被本身实例和子类实例使用'  # 以单下划线开头的表示的是 protected 类型的变量，即保护类型只能允许其本身与子类进行访问，不能用于 from module import *
    __private_val = '我是私有变量，只能被内部（类和对象实例）使用'

    def __init__(self):
        print("调用父类构造函数")

    def parent_method(self):
        print('调用父类方法')

    def set_attr(self, attr):
        Parent.parentAttr = attr

    def get_attr(self):
        print("父类属性 :", Parent.parentAttr)

    def get_private_val(self):
        print('私有变量:', Parent.__private_val)
        # Parent.__private_method() Parent.__private_val
        # self.__private_method() self.__private_method()

    def _protect_method(self):
        print('本身或子类能使用')

    def __private_method(self):
        print('私有方法,只能被内部使用')

    @classmethod
    def static_method_c(cls):
        print('我是静态方法')


class Child(Parent):  # 定义子类
    def __init__(self):
        print("调用子类构造方法")

    def child_method(self):
        print('调用子类方法 child method')

    def parent_method(self):
        super().parent_method()
        print('重载父类方法 parent method，我要重新实现它')


'''
类属性与方法

类的私有属性
__private_attrs：两个下划线开头，声明该属性为私有，不能在类地外部被使用或直接访问。在类内部的方法中使用时 self.__private_attrs。

类的方法
在类地内部，使用def关键字可以为类定义一个方法，与一般函数定义不同，类方法必须包含参数self,且为第一个参数

类的私有方法
__private_method：两个下划线开头，声明该方法为私有方法，不能在类地外部调用。在类的内部调用 self.__private_methods
'''

c = Child()  # 实例化子类
c.child_method()  # 调用子类的方法
c.parent_method()  # 调用父类方法
c.set_attr(200)  # 再次调用父类的方法
c.get_attr()  # 再次调用父类的方法
print(c._protected_val)
print(c.get_private_val())
c._protect_method()
# c.__private_method() #私有属性或方法外部无法使用
# print(c.__private_val)
# print(Parent.__private_val)
# p = Parent()
# p.__private_val
Child.static_method_c()
Parent.static_method_c()

'''基础运算符重载'''


class Vector(object):
    def __init__(self, a, b):
        self.a = a
        self.b = b

    def __str__(self):
        return 'Vector(%d, %d)' % (self.a, self.b)

    def __add__(self, other):
        return Vector(self.a + other.a, self.b + other.b)

    def __sub__(self, other):
        return Vector(self.a - other.a, self.b - other.b)


v1 = Vector(2, 10)
v2 = Vector(5, -2)
print(v1.__add__(v2), v1 + v2)
print(v1.__sub__(v2), v1 - v2)
